package fr.skolian.utils.capture.core
{
	import flash.desktop.NativeProcess;
	import flash.desktop.NativeProcessStartupInfo;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.NativeProcessExitEvent;
	import flash.events.ProgressEvent;
	import flash.filesystem.File;
	
	import fr.skolian.utils.log.Log;
	import fr.skolian.utils.process.event.ProcessEvent;
	
	
	
/*Skolian - Content management system for primary school - Copyright (c) 2011 - Olivier Gianotti - This file is part of Skolian. Skolian is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Skolian is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Skolian.  If not, see <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 

Skolian - Application de gestion de contenus pédagogiques en école primaire. Copyright (C) 2011 - Olivier Gianotti - Ce fichier est une partie de Skolian. Skolian est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier au titre des clauses de la Licence Publique Générale GNU, telle que publiée par la Free Software Foundation ; soit la version 2 de la Licence, ou (à votre discrétion) une version ultérieure quelconque. Ce programme est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE ; sans même une garantie implicite de COMMERCIABILITE ou DE CONFORMITE A UNE UTILISATION PARTICULIERE. Voir la Licence Publique Générale GNU pour plus de détails. Vous devriez avoir reçu un exemplaire de la Licence Publique Générale GNU avec ce programme ; si ce n'est pas le cas, consultez <http://www.gnu.org/licenses/>.
contact : ogianotti@gmail.com 
*/

public class Capture extends EventDispatcher
	{
		
		private var _process:NativeProcess;
		private var _exe:File;
		private var _completeMessage:String;
		
		public function Capture()
		{
			super();
			_exe = File.applicationDirectory;
			_exe = _exe.resolvePath("assets/process/screencapture.sh");
		}
		
		public function execute(name:String=null,fullScreen:Boolean=false):void{
			_completeMessage = "screencapture save to file: "+name;
			var vector:Vector.<String> = new Vector.<String>();
			vector.push("-c");
			if(!fullScreen)vector.push("-i");
			if(name)vector.push(name);
			createProcess(vector);
		}
		
		
		private function createProcess(args:Vector.<String>):void{
			kill();
			_process = new NativeProcess();
			_process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOut);
			_process.addEventListener(Event.STANDARD_OUTPUT_CLOSE,onOutPutClose);
			_process.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onStandardInput);
			_process.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR,onError);
			_process.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR,onError);
			_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorOut);
			_process.addEventListener(NativeProcessExitEvent.EXIT, onProcessExit);
			
			var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
			nativeProcessStartupInfo.workingDirectory = File.applicationDirectory;
			nativeProcessStartupInfo.executable = _exe;
			nativeProcessStartupInfo.arguments = args;
			_process.start(nativeProcessStartupInfo);
			
			Log.log("start process");
		}
	
		private function getProcessFilePATH(url:String):String{
			var file:File = new File()
			file = File.applicationDirectory;
			file = file.resolvePath(url);
			var reg:RegExp = /([ '""`])/g;
			return String(file.nativePath).replace(reg, "\\$1");
		}
		
		protected function onOutPutClose(e:Event):void
		{
			
		}
		
		protected function onStandardOut(e:ProgressEvent):void
		{
			var message:String = _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);	
			Log.log("output message "+message);
			dispatchEvent(new ProcessEvent(ProcessEvent.PROGRESS,message));
			if(_completeMessage && message.replace(/\n/g,"").indexOf(_completeMessage)>-1 ){
				_completeMessage = null;
				dispatchEvent(new ProcessEvent(ProcessEvent.FINISH,"finish the execution"));	
			}
		}
		
		protected function onStandardInput(e:ProgressEvent):void
		{
		}
		
		protected function onError(e:IOErrorEvent):void
		{
			dispatchEvent(new ProcessEvent(ProcessEvent.ERROR,_process.standardError.readUTFBytes(_process.standardError.bytesAvailable)));
		}
		
		protected function onErrorOut(e:ProgressEvent):void
		{
			var message:String = _process.standardError.readUTFBytes(_process.standardError.bytesAvailable);
			dispatchEvent(new ProcessEvent(ProcessEvent.ERROR,message));
		}
		
		protected function onProcessExit(e:NativeProcessExitEvent):void
		{
			dispatchEvent(new ProcessEvent(ProcessEvent.FINISH,"finish the execution"));
		}
		
		public function clear():void{
			if(!_process)return;
			_process.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOut);
			_process.removeEventListener(Event.STANDARD_OUTPUT_CLOSE,onOutPutClose);
			_process.removeEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onStandardInput);
			_process.removeEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR,onError);
			_process.removeEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR,onError);
			_process.removeEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorOut);
			_process.removeEventListener(NativeProcessExitEvent.EXIT, onProcessExit);
		}
		
		public function kill():void{
			if(_process && _process.running){
				try{_process.closeInput();}catch(error:Error){};
				_process.exit(true);
			}
			clear();
			_process = null;
		}
	}
}